import 'dart:math';
import 'package:flutter/material.dart';

/*
 * @author[hansen]
 * @date[创建日期: 2022/7/19 18:06]
 * @version[版本: v1.0]
 * @function[功能简介: 评分widget]
 */

class StarRatingWidget extends StatefulWidget {
  final double starRating;
  final double maxStarRating;
  final double starSize;
  final double starSpace;
  final double badStarRating;
  final double goodStarRating;
  final int starCount;

  final Widget? starIcon;
  final Widget? selectedStarIcon;

  final String badText;
  final String commonText;
  final String goodText;
  final TextStyle textStyle;
  final bool showText;
  final bool disabled;

  ///回调
  final Function(double)? onStarRatingChange;

  const StarRatingWidget({
    Key? key,
    this.starRating = 0,
    this.maxStarRating = 5,
    this.starSize = 22,
    this.starSpace = 5,
    this.badStarRating = 3,
    this.goodStarRating = 5,
    this.starCount = 5,
    this.starIcon,
    this.selectedStarIcon,
    this.showText = false,
    this.disabled = false,
    this.badText = "差",
    this.commonText = "一般",
    this.goodText = "好",
    this.textStyle = const TextStyle(
      fontSize: 14,
      color: Color(0xff333333),
    ),
    this.onStarRatingChange,
  }) : super(key: key);

  @override
  State<StarRatingWidget> createState() => _StarRatingWidgetState();
}

class _StarRatingWidgetState extends State<StarRatingWidget> {
  double currentStarRating = 0;

  @override
  void initState() {
    super.initState();

    currentStarRating = widget.starRating;
  }

  @override
  Widget build(BuildContext context) {
    double moveStarRating = currentStarRating;

    return GestureDetector(
      onTapDown: (TapDownDetails details) {
        if (widget.disabled) return;

        moveStarRating =
            (details.localPosition.dx / (widget.starSize + widget.starSpace))
                .ceilToDouble();

        if (moveStarRating == currentStarRating.ceilToDouble()) return;

        currentStarRating = moveStarRating;

        if (widget.onStarRatingChange != null) {
          widget.onStarRatingChange!(currentStarRating);
        }

        setState(() {});
      },
      onHorizontalDragUpdate: (DragUpdateDetails details) {
        if (widget.disabled) return;

        moveStarRating =
            (details.localPosition.dx / (widget.starSize + widget.starSpace))
                .ceilToDouble();

        if (moveStarRating == currentStarRating.ceilToDouble()) return;

        currentStarRating = moveStarRating;

        if (widget.onStarRatingChange != null) {
          widget.onStarRatingChange!(currentStarRating);
        }

        setState(() {});
      },
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: List.generate(
            widget.showText ? widget.starCount + 1 : widget.starCount, (index) {
          if (index == widget.starCount) {
            return Padding(
              padding: EdgeInsets.only(left: widget.starSpace),
              child: Text(
                currentStarRating <= 0
                    ? ""
                    : currentStarRating < widget.badStarRating
                        ? widget.badText
                        : currentStarRating < widget.goodStarRating
                            ? widget.commonText
                            : widget.goodText,
                style: widget.textStyle,
              ),
            );
          }

          if (index <= currentStarRating - 1) {
            return Padding(
              padding: EdgeInsets.only(
                left: index > 0 ? widget.starSpace : 0,
              ),
              child: widget.selectedStarIcon ??
                  Icon(
                    Icons.star,
                    size: widget.starSize,
                    color: const Color(0xffC20014),
                  ),
            );
          }

          return Padding(
            padding: EdgeInsets.only(
              left: index > 0 ? widget.starSpace : 0,
            ),
            child: widget.starIcon ??
                Icon(
                  Icons.star_border,
                  size: widget.starSize,
                  color: const Color(0xffC0C4CC),
                ),
          );
        }),
      ),
    );
  }
}
